home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Macintosh Sample Code / SC.013.OOPTESample / UTESample.inc1.p < prev    next >
Encoding:
Text File  |  1994-11-18  |  9.9 KB  |  377 lines  |  [TEXT/MPS ]

  1. {---------------------------------------------------------------------
  2. #
  3. #    Apple Macintosh Developer Technical Support
  4. #
  5. #    MultiFinder-Aware Simple TextEdit Sample Application
  6. #
  7. #    OOPTESample
  8. #
  9. #    UTESample.inc1.p        -    Pascal Source
  10. #
  11. #    Copyright © 1988, 1989 Apple Computer, Inc.
  12. #    All rights reserved.
  13. #
  14. #    Versions:        
  15. #                    1.00                    04/89
  16. #                    1.10                    02/90
  17. #                    1.11                    10/92
  18. #
  19. #    Components:     
  20. #                    BuildOOPTESample            February 1, 1990
  21. #                    MTESample.p                    February 1, 1990
  22. #                    OOPTESample.make            February 1, 1990
  23. #                    TECommon.h                    February 1, 1990
  24. #                    TESampleGlue.a                February 1, 1990
  25. #                    TESample.r                    February 1, 1990
  26. #                    TMLRules.make                February 1, 1990
  27. #                    UApplication.p                February 1, 1990
  28. #                    UApplication.inc1.p            February 1, 1990
  29. #                    UDocument.p                    February 1, 1990
  30. #                    UDocument.inc1.p            February 1, 1990
  31. #                    UTEDocument.p                February 1, 1990
  32. #                    UTEDocument.inc1.p            February 1, 1990
  33. #                    UTESample.p                    February 1, 1990
  34. #                    UTESample.inc1.p            February 1, 1990
  35. #
  36. ---------------------------------------------------------------------}
  37.  
  38. CONST
  39.     rMenuBar    = 128;
  40.     rDocWindow    = 128;                { application's window }
  41.     rAboutAlert    = 128;                { about alert }
  42.  
  43.     { The following constants are used to identify menus and their items. The menu IDs }
  44.     { have an "m" prefix and the item numbers within each menu have an "i" prefix. }
  45.     mApple        = 128;                {Apple menu}
  46.     iAbout        = 1;
  47.  
  48.     mFile        = 129;                { File menu }
  49.     iNew        = 1;
  50.     iClose        = 4;
  51.     iQuit        = 12;
  52.  
  53.     mEdit        = 130;                { Edit menu }
  54.     iUndo        = 1;
  55.     iCut        = 3;
  56.     iCopy        = 4;
  57.     iPaste        = 5;
  58.     iClear        = 6;
  59.  
  60.     kMinSize        = 40;
  61.     kMaxSleepTime    = 60;
  62.     kSleepTime        = $7FFFFFFF;
  63.  
  64.     kExtremePos        = 32767 - 1;    { required for old region bug }
  65.     kExtremeNeg        = -32768;        {kExtremePos and kExtremeNeg are used to set up
  66.                                     wide open rectangles and regions.}
  67.  
  68.     kMaxOpenDocuments        = 1;    {kMaxOpenDocuments is used to determine whether
  69.                                     a new document can be opened or created. We keep
  70.                                     track of the number of open documents, and disable
  71.                                     the menu items that create a new document when the
  72.                                     maximum is reached. If the number of documents falls
  73.                                     below the maximum, the items are enabled again.}
  74.  
  75. (********************************************************************************************)
  76. (*        T T E S a m p l e                                                                    *)
  77. (********************************************************************************************)
  78. {$S Initialize}
  79. {-----------------------------------+
  80. |    ITESample                        |
  81. +-----------------------------------}
  82. PROCEDURE TTESample.ITESample;
  83. VAR
  84.     menuBar: Handle;
  85. BEGIN
  86.     IApplication;
  87.     
  88.     { Read menus into menubar }
  89.     menuBar := GetNewMBar(rMenuBar);
  90.     
  91.     { Install menus }
  92.     SetMenuBar(menuBar);
  93.     DisposeHandle(menuBar);
  94.     
  95.     { Add DA names to Apple menu }
  96.     AppendResMenu(GetMenuHandle(mApple),'DRVR');
  97.     DrawMenuBar;
  98.     
  99.     { Create empty mouse region }
  100.     fMouseRgn := NewRgn;
  101.     
  102.     { Create a single empty document }
  103.     DoNew;
  104.     
  105.     {Make sure we have a valid cursor region }
  106.     AdjustCursor;
  107. END;
  108.  
  109. {$S Main}
  110. {-----------------------------------+
  111. |    DoIdle                            |
  112. +-----------------------------------}
  113. { This is called whenever we get a NULL event et al. }
  114. { It takes care of necessary periodic actions. For this program, }
  115. { it calls the DoIdle method of the current document. }
  116. PROCEDURE TTESample.DoIdle; OVERRIDE;
  117. VAR
  118.     fTECurDoc: TTEDocument;
  119. BEGIN
  120.     fTECurdoc := TTEDocument(fCurDoc);
  121.     IF fTECurDoc <> NIL THEN
  122.         fTECurDoc.DoIdle;
  123. END;
  124.  
  125. {$S Main}
  126. {-----------------------------------+
  127. |    AdjustMenus                        |
  128. +-----------------------------------}
  129. { Enable and disable menus based on the current state. The }
  130. { user can only select enabled menu items. We set up all the }
  131. { menu items before calling MenuSelect or MenuKey, since }
  132. { these are the only times that a menu item can be selected. }
  133. { Note that MenuSelect is also the only time the user will }
  134. { see menu items. This approach to deciding what enable/ }
  135. { disable state a menu item has the advantage of }
  136. { concentrating all the decision-making in one routine, as }
  137. { opposed to being spread throughout the application. Other }
  138. { application designs may take a different approach that may }
  139. { or may not be as valid.  }
  140.  
  141. PROCEDURE TTESample.AdjustMenus; OVERRIDE;
  142. VAR
  143.     frontMost:    WindowPtr;
  144.     menu:        MenuHandle;
  145.     offset:        longint;
  146.     undo:        Boolean;
  147.     cutCopyClear:    Boolean;
  148.     paste:        Boolean;
  149.     fTECurDoc:    TTEDocument;
  150. BEGIN
  151.     fTECurdoc := TTEDocument(fCurDoc);
  152.     frontMost := FrontWindow;
  153.     
  154.     menu := GetMenuHandle(mFile);
  155.     IF (fDocList.NumDocs < kMaxOpenDocuments) THEN
  156.         EnableItem(menu,iNew)
  157.     ELSE
  158.         DisableItem(menu,iNew);
  159.     IF (frontMost <> NIL) THEN
  160.         EnableItem(menu,iClose)
  161.     ELSE
  162.         DisableItem(menu,iClose);
  163.         
  164.     menu := GetMenuHandle(mEdit);
  165.     undo := FALSE;
  166.     cutCopyClear := FALSE;
  167.     paste := FALSE;
  168.     IF (frontMost <> NIL) THEN 
  169.         IF (fTECurDoc = NIL) THEN BEGIN        { all editing is enabled for DA windows }
  170.             undo := TRUE;
  171.             cutCopyClear := TRUE;
  172.             paste := TRUE;
  173.         END ELSE BEGIN
  174.             { Cut, Copy, and Clear is enabled for app. windows with selections  }
  175.             IF fTECurDoc.HaveSelection THEN
  176.               cutCopyClear := TRUE;
  177.             { If we have any TEXT in the scrap, enable paste }
  178.             IF GetScrap(NIL, 'TEXT', offset) > 0 THEN
  179.                 paste := TRUE; 
  180.         END;
  181.     
  182.     IF undo THEN
  183.         EnableItem(menu,iUndo)
  184.     ELSE
  185.         DisableItem(menu,iUndo);
  186.     IF cutCopyClear THEN BEGIN
  187.         EnableItem(menu,iCut);
  188.         EnableItem(menu,iCopy);
  189.         EnableItem(menu,iClear);
  190.     END ELSE BEGIN
  191.         DisableItem(menu,iCut);
  192.         DisableItem(menu,iCopy);
  193.         DisableItem(menu,iClear);
  194.     END;
  195.     IF paste THEN
  196.         EnableItem(menu,iPaste)
  197.     ELSE
  198.         DisableItem(menu,iPaste);
  199. END;
  200.  
  201. {$S Main}
  202. {-----------------------------------+
  203. |    AdjustCursor                    |
  204. +-----------------------------------}
  205. { Change the cursor's shape, depending on its position. This also calculates a }
  206. { region that includes the cursor for WaitNextEvent. }
  207. PROCEDURE TTESample.AdjustCursor; OVERRIDE;
  208. VAR
  209.     fTECurDoc:    TTEDocument;
  210.     arrowRgn,
  211.     iBeamRgn:    RgnHandle;
  212.     mouse:        Point;
  213. BEGIN
  214.     fTECurdoc := TTEDocument(fCurDoc);
  215.     
  216.     { Notice that we don't change the cursor if front window isn't ours }
  217.     IF (NOT(fInBackGround) AND (fTECurDoc <> NIL)) THEN BEGIN
  218.     
  219.         GetMouse(mouse);
  220.         LocalToGlobal(mouse);
  221.         
  222.         arrowRgn := NewRgn;
  223.         iBeamRgn := NewRgn;
  224.         
  225.         SetRectRgn(arrowRgn,kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
  226.         
  227.         fTECurDoc.GetVisTERgn(iBeamRgn);
  228.         
  229.         DiffRgn(arrowRgn,iBeamRgn,arrowRgn);
  230.         
  231.         IF PtInRgn(mouse,iBeamRgn) THEN BEGIN
  232.             SetCursor(GetCursor(iBeamCursor)^^);
  233.             CopyRgn(iBeamRgn,fMouseRgn);
  234.         END ELSE BEGIN
  235.             SetCursor(qd.arrow);
  236.             CopyRgn(arrowRgn,fMouseRgn);
  237.         END;
  238.         DisposeRgn(arrowRgn);
  239.         DisposeRgn(iBeamRgn);
  240.     END;
  241. END;
  242.  
  243. {$S Main}
  244. {-----------------------------------+
  245. |    DoMenuCommand                    |
  246. +-----------------------------------}
  247. { This is called when an item is chosen from the menu bar (after calling }
  248. { MenuSelect or MenuKey). It does the right thing for each command. }
  249. PROCEDURE TTESample.DoMenuCommand(menuID,menuItem: integer); OVERRIDE;
  250. VAR
  251.     itemHit:    integer;
  252.     daName:        Str255;
  253.     daRefNum:    integer;
  254.     window:        WindowPtr;
  255.     fTECurDoc: TTEDocument;
  256. BEGIN
  257.     fTECurdoc := TTEDocument(fCurDoc);
  258.     window := FrontWindow;
  259.     
  260.     CASE menuID OF
  261.         mApple:
  262.             CASE menuItem OF
  263.                 iAbout:                    { bring up alert for About  }
  264.                     itemHit := Alert(rAboutAlert, NIL);
  265.                 OTHERWISE BEGIN            { all non-About items in this menu are DAs et al  }
  266.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
  267.                     daRefNum := OpenDeskAcc(daName);
  268.                 END; { OTHERWISE }
  269.             END; { CASE menuItem }
  270.         mFile:
  271.             CASE menuItem OF
  272.                 iNew:
  273.                     DoNew;
  274.                 iClose:
  275.                     BEGIN
  276.                         IF fTECurDoc <> NIL THEN BEGIN
  277.                             fDocList.RemoveDoc(fTECurDoc);
  278.                             fTECurDoc.Free;
  279.                         END ELSE BEGIN
  280.                             CloseDeskAcc(WindowPeek(fWhichWindow)^.windowKind);
  281.                         END;
  282.                         
  283.                         { make sure our current document/window references are valid }
  284.                         window := FrontWindow;
  285.                         IF window <> NIL THEN BEGIN
  286.                             fCurDoc := fDocList.FindDoc(window);
  287.                             SetPort(window);
  288.                         END ELSE BEGIN
  289.                             fCurDoc := NIL;
  290.                         END;
  291.                     END;
  292.  
  293.                 iQuit:
  294.                     Terminate;
  295.             END; { CASE menuItem }
  296.         mEdit:                    { call SystemEdit for DA editing & MultiFinder  }
  297.             IF NOT SystemEdit(menuItem-1) THEN
  298.                  CASE menuItem OF
  299.                     iCut:    fTECurDoc.DoCut;
  300.                     iCopy:    fTECurDoc.DoCopy;
  301.                     iPaste:    fTECurDoc.DoPaste;
  302.                     iClear:    fTECurDoc.DoClear;
  303.                 END; { CASE menuItem }
  304.     END;
  305.     HiliteMenu(0);
  306. END; { doMenuCommand }
  307.  
  308. {$S Main}
  309. {-----------------------------------+
  310. |    HeapNeeded                        |
  311. +-----------------------------------}
  312. FUNCTION TTESample.HeapNeeded: Longint; OVERRIDE;
  313. BEGIN
  314.     HeapNeeded := kMinSize * 1024;
  315. END;
  316.  
  317. {$S Main}
  318. {-----------------------------------+
  319. |    SleepVal                        |
  320. +-----------------------------------}
  321.  
  322. { Calculate a sleep value for WaitNextEvent. This takes into account the things }
  323. { that DoIdle does with Idle Time. The formula used here is: 
  324.     IF we are in the foreground
  325.     AND our document window is in front
  326.     THEN
  327.         SleepVal := whatever the front document says it should be
  328.     ELSE
  329.         SleepVal := aRealLongTime
  330.         
  331.     After that, SleepVal is clipped to kMaxSleepTime which is currently set
  332.     to 60 ticks. This is to account for a Notification Manager bug wherein
  333.     notifications don't occur while the front application is asleep. }
  334.  
  335. FUNCTION TTESample.SleepVal: LongInt; OVERRIDE;
  336. VAR
  337.     sleep: longint;
  338.     fTECurDoc: TTEDocument;
  339. BEGIN
  340.     sleep := kSleepTime;
  341.     fTECurdoc := TTEDocument(fCurDoc);
  342.     IF ((NOT fInBackGround) AND (fTECurdoc <> NIL)) THEN BEGIN
  343.         sleep := fTECurDoc.CalcIdle;
  344.     END;
  345.     IF sleep > kMaxSleepTime THEN
  346.         sleep := kMaxSleepTime;
  347.     SleepVal := sleep;
  348. END;
  349.  
  350. {$S Initialize}
  351. {-----------------------------------+
  352. |    DoNew                            |
  353. +-----------------------------------}
  354. { Create a new document and window.  }
  355. PROCEDURE TTESample.DoNew;
  356. VAR
  357.     tDoc:    TTEDocument;
  358. BEGIN
  359.     New(tdoc);
  360.     tDoc.ITEDocument(rDocWindow);
  361.     
  362.     IF tdoc <> NIL THEN
  363.         fdocList.Adddoc(tdoc);
  364. END;
  365.  
  366. {$S Main}
  367. {-----------------------------------+
  368. |    Terminate                        |
  369. +-----------------------------------}
  370. { Clean up the application and exits. We close all of the windows so that }
  371. { they can update their documents. }
  372. PROCEDURE TTESample.Terminate;
  373. BEGIN
  374.     { FIX: close all docs }
  375.     ExitLoop;
  376. END;
  377.